package com.chk.gateway.filter;

import com.chk.commom.constants.AppHttpCodeEnum;
import com.chk.commom.utils.CommonResult;
import com.chk.commom.utils.JwtUtil;
import com.chk.commom.utils.VoidJudgeUtils;
import com.chk.gateway.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.PathContainer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    private static final List<String> NO_FILTER_PATHS = new ArrayList<>();
    static{                                        //不需验证的
        NO_FILTER_PATHS.add("/user/code");         // 验证码
        NO_FILTER_PATHS.add("/user/login");         // 登录
    }
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //有限制的地址  获取token 验证权限
        //获得请求和响应对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //获取用户ip
        String  requestIp = String.valueOf(request.getRemoteAddress());
        String  requestHost = Objects.requireNonNull(request.getRemoteAddress()).getHostName();



        // 获取请求地址
        PathContainer pathContainer = exchange.getRequest().getPath().pathWithinApplication();
        String path = pathContainer.toString(); // 路径

        String SysRegex = "/sys/.*";
        String AuthRegex =  "/auth/.*";

        if(path.matches(AuthRegex)){
            log.info("主机ip : "+requestIp+" 主机号 : "+ requestHost +"   访问用户接口 : "+ path);
        }else if(path.matches(SysRegex)){
            log.info("主机ip : "+requestIp+" 主机号 : "+ requestHost +"   访问管理接口 : "+ path);
        }else {
            log.info("主机ip : "+requestIp+" 主机号 : "+ requestHost +"   访问游客接口 : "+ path);
        }

        if (NO_FILTER_PATHS.contains(path)) {
            // 无需限制的地址,继续执行 不需要token
            return chain.filter(exchange);
        }

        //获得请求参数
        String token = request.getHeaders().getFirst("token");
        if(VoidJudgeUtils.isBlank(token)){
            response.setStatusCode(HttpStatus.FORBIDDEN);
            DataBuffer wrap = response.bufferFactory().wrap("内容需要登录才嫩查看！".getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(wrap));
        }
        //获取token的用户角色信息
        User user = new User();
        try {
            user = JwtUtil.parseToken(token, User.class);
        } catch (Exception e) {
            DataBuffer buffer = response.bufferFactory().wrap("token无效，请重新登录!".getBytes());
            return response.writeWith(Mono.just(buffer));
        }
        String role = user.getRole();
        if(Objects.equals(role, "2")){
            return chain.filter(exchange);
        }else if(Objects.equals(role, "0")){
            DataBuffer buffer = response.bufferFactory().wrap("用户已被封禁！请联系管理员！".getBytes());
            return response.writeWith(Mono.just(buffer));
        }else if(Objects.equals(role, "1")){ // 普通用户
            //判断访问地址的浅醉
            if(path.matches(AuthRegex)){//匹配到普通的 接口
                return chain.filter(exchange);
            }
            DataBuffer buffer = response.bufferFactory().wrap("权限不足".getBytes());
            return response.writeWith(Mono.just(buffer));
        }
        DataBuffer buffer = response.bufferFactory().wrap("未知原因，请稍后再试或联系管理员！".getBytes());
        return response.writeWith(Mono.just(buffer));

    }

    /**
     * 优先级 小的优先
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
